package api

import (
	"go-iot/app/common/boot"
	"go-iot/app/iot/cluster"
	"go-iot/app/iot/core"
	"go-iot/app/models"
	"go-iot/app/models/device"
	"go-iot/app/models/network"
	"go-iot/app/models/notify"
	"go-iot/app/models/rule"
	"go-iot/app/iot/network/servers"
	notify1 "go-iot/app/iot/notify"
	"go-iot/app/iot/ruleengine"
	"go-iot/app/common/logger"
)

func init() {
	boot.AddStartLinstener(func() {
		start := &start{}
		go start.startRuningNetServer()
		go start.startRuningRule()
		go start.startRuningNotify()
		go start.startRuningNetClient()
	})
}

type start struct {
}

func (i *start) startRuningRule() {
	
	// 使用 AllRule 替代 PageRule
	list, err := rule.AllRule(models.Started)
	if err != nil {
		logger.Errorf("get rules error: %v", err)
		return
	}
	
	for _, r := range list {
		m, err := rule.GetRuleMust(r.Id)
		if err != nil {
			logger.Errorf("get rule error: %v", err)
			continue
		}
		rule := ruleModelToRuleExecutor(m)
		err = ruleengine.Start(m.Id, &rule)
		if err != nil {
			logger.Errorf("start rule error: %v", err)
			continue
		}
	}
	
	logger.Infof("start runing rule done")
}

func (i *start) startRuningNotify() {
	
	list, err := notify.ListAll(&models.Notify{State: models.Started}, nil)
	if err != nil {
		logger.Errorf("start notify error: %v", err)
		return
	}
	
	for _, m := range list {
		config := notify1.NotifyConfig{Config: m.Config, Template: m.Template}
		err = notify1.EnableNotify(m.Type, m.Id, config)
		if err != nil {
			logger.Errorf("start notify error: %v", err)
		}
	}
	
	logger.Infof("start runing notify done")
}

func (i *start) startRuningNetServer() {
    
    networks, err := network.AllNetwork()
    if err != nil {
        logger.Errorf("start network error: %v", err)
        return
    }
    
    for _, nw := range networks {
        if nw.State == models.Runing {
            config, err := convertCodecNetwork(nw)
            if err != nil {
                logger.Errorf("start network error: %v", err)
                continue
            }
            err = servers.StartServer(config)
            if err != nil {
                logger.Errorf("start network error: %v", err)
            }
        }
    }
    
    logger.Infof("start runing network done")
}

func (i *start) startRuningNetClient() {
    
    networks, err := network.AllNetwork()
    if err != nil {
        logger.Errorf("start netclient error: %v", err)
        return
    }
    
    for _, nw := range networks {
        if len(nw.Configuration) > 0 && nw.Port == 0 && nw.ProductId != "" {
            var devicePage models.PageQuery
            devicePage.PageSize = 300
            devicePage.Condition = []core.SearchTerm{{Key: "State", Value: core.OFFLINE}, {Key: "productId", Value: nw.ProductId}}
            r1, err := device.PageDevice(&devicePage, nil)
            if err != nil {
                logger.Errorf("start netclient error: %v", err)
                continue
            }
            devicePage.SearchAfter = r1.SearchAfter
            devices := r1.List
            if len(devices) == 0 {
                continue
            }
            for _, dev := range devices {
                if cluster.Enabled() {
                    if cluster.Shard(dev.Id) {
                        err = connectClientDevice(dev.Id)
                    }
                } else {
                    err = connectClientDevice(dev.Id)
                }
                if err != nil {
                    logger.Errorf("start netclient error: %v", err)
                }
            }
        }
    }
    
    logger.Infof("start runing netclient done")
}
